home *** CD-ROM | disk | FTP | other *** search
- #include "mesh.hpp"
-
- // Copyright (c) 1996 by Kerrigan Burgess, all rights reserved.
-
-
- int SHADING; // flag. which type? (Constant,Gouraud,Phong,Flat).
- int TEXTUREMAPPED; // flag. Is it Texture Mapped?
- int TRANSPARENCY; // flag. Is it enabled? (opaque/transparent).
- int MORPHING; // flag. Is it enabled?
- int SHADOWING; // flag. Are shadows enabled?
- int HAZING; // flag. Is hazing on?
-
- POLYGONCLASS **MeshList; // for final rendering.
- int meshindex; // index for MeshList.
- int shadowindex; // how many shadows per frame.
-
- void ComputeAvgZ(void)
- {
- int count;
- POLYGONCLASS *ThisPolygon;
-
- for (count=shadowindex;count<meshindex;count++)
- {
- ThisPolygon = MeshList[count];
- ThisPolygon->avgz=(float)0.33333*( (ThisPolygon->Vertex[0])->z +
- (ThisPolygon->Vertex[1])->z +
- (ThisPolygon->Vertex[2])->z );
- }
- }
-
- int PolyCompare(const void *arg1, const void *arg2)
- {
- POLYGONCLASS *Poly1,*Poly2;
-
- Poly1=*(POLYGONCLASS **)arg1;
- Poly2=*(POLYGONCLASS **)arg2;
-
- if (Poly1->avgz > Poly2->avgz)
- return (-1);
- else
- if (Poly1->avgz < Poly2->avgz)
- return (1);
- else
- return (0);
- }
-
- LIGHTCLASS::LIGHTCLASS(void) // Constructor.
- {
- lightsource.x=0; // light is at origin.
- lightsource.y=0;
- lightsource.z=0;
- }
-
- LIGHTCLASS::~LIGHTCLASS(void) // Destructor.
- {
-
- }
-
- LIGHTCLASS::SetLight(float x, float y, float z)
- {
- // set light in world coords.
-
- lightsource.x=x;
- lightsource.y=y;
- lightsource.z=z;
-
- infinitelightsource.x=x;
- infinitelightsource.y=y;
- infinitelightsource.z=z*1000; // set it pretty dammed far.
- }
-
- POINT3D *LIGHTCLASS::GetLight(void)
- {
- return (&lightsource);
- }
-
- POINT3D *LIGHTCLASS::GetInfiniteLight(void)
- {
- return (&infinitelightsource);
- }
-
- CAMERACLASS::CAMERACLASS(void) // Constructor.
- {
- viewpoint.x=0;
- viewpoint.y=0;
- viewpoint.z=0;
- angx=0;
- angy=0;
- angz=0;
- }
-
- CAMERACLASS::~CAMERACLASS(void) // Destructor.
- {
-
- }
-
- void CAMERACLASS::SetViewPoint(float viewx, float viewy, float viewz)
- {
- viewpoint.x = viewx;
- viewpoint.y = viewy;
- viewpoint.z = viewz;
- }
-
- void CAMERACLASS::MoveViewPoint(float viewx, float viewy, float viewz)
- {
- viewpoint.x+=viewx;
- viewpoint.y+=viewy;
- viewpoint.z+=viewz;
- }
-
- POINT3D *CAMERACLASS::GetViewPoint(void)
- {
- return (&viewpoint);
- }
-
- void CAMERACLASS::SetViewAngle(int angle_x, int angle_y, int angle_z)
- {
- angx=angle_x;
- angy=angle_y;
- angz=angle_z;
- }
-
- void CAMERACLASS::MoveViewAngle(int angle_x, int angle_y, int angle_z)
- {
- angx+=angle_x;
- angy+=angle_y;
- angz+=angle_z;
- }
-
- void CAMERACLASS::CreateCameraMatrix(MATRIX CameraMatrix)
- {
- double Xa,Ya,Za;
- float Sx,Cx,Sy,Cy,Sz,Cz;
-
- // Change degree to radian
- Xa = -angx*6.281/360;
- Ya = -angy*6.281/360;
- Za = -angz*6.281/360;
-
- Sx = (float)sin ( Xa );
- Cx = (float)cos ( Xa );
- Sy = (float)sin ( Ya );
- Cy = (float)cos ( Ya );
- Sz = (float)sin ( Za );
- Cz = (float)cos ( Za );
-
- //T*Y*X*Z;
- CameraMatrix[0][0] = Cy*Cz+Sy*Sx*Sz;
- CameraMatrix[0][1] = -Cy*Sz+Sy*Sx*Cz;
- CameraMatrix[0][2] = Sy*Cx;
- CameraMatrix[0][3] = 0;
-
- CameraMatrix[1][0] = Cx*Sz;
- CameraMatrix[1][1] = Cx*Cz;
- CameraMatrix[1][2] = -Sx;
- CameraMatrix[1][3] = 0;
-
- CameraMatrix[2][0] = -Sy*Cz+Cy*Sx*Sz;
- CameraMatrix[2][1] = Sy*Sz+Cy*Sx*Cz;
- CameraMatrix[2][2] = Cy*Cx;
- CameraMatrix[2][3] = 0;
-
- CameraMatrix[3][0] = -viewpoint.x*(Cy*Cz+Sy*Sx*Sz)
- -viewpoint.y*(Cx*Sz)
- -viewpoint.z*(-Sy*Cz+Cy*Sx*Sz);
- CameraMatrix[3][1] = -viewpoint.x*(-Cy*Sz+Sy*Sx*Cz)
- -viewpoint.y*(Cx*Cz)
- -viewpoint.z*(Sy*Sz+Cy*Sx*Cz);
- CameraMatrix[3][2] = -viewpoint.x*(Sy*Cx)
- -viewpoint.y*(-Sx)
- -viewpoint.z*(Cy*Cx);
- CameraMatrix[3][3] = 1;
- }
-
- MESHCLASS::MESHCLASS(void) // constructor.
- {
- ObjectHead = NULL;
-
- meshindex=0; // index for rendering list.
- shadowindex=0; // how shadows in frame.
- totalfaces=0;
-
- MAX_LIGHTS = 1;
- Light = new LIGHTCLASS [MAX_LIGHTS];
-
- Light[0].SetLight(0,0,-1);
-
- _CURRENTCAMERA_ = 0;
- MAX_CAMERAS = 4;
- Camera = new CAMERACLASS [MAX_CAMERAS];
-
- int count;
- for (count=0;count<MAX_CAMERAS;count++)
- Camera[count] = CAMERACLASS(); // call constructor to initialize
-
- velangx=0;
- velangy=0;
- velangz=0;
- angx=0; // initialize rotation angles.
- angy=0;
- angz=0;
- tx=ty=tz=0; // initialize translation vectors.
-
- translevel=0; // start no transparency.
-
- MORPHING=FALSE; // set morph to False.
- SHADING = Gouraud; // default to Gouraud shading.
- TEXTUREMAPPED = NoTexture; // default to no texture.
- TRANSPARENCY = Opaque; // shut off transparency.
- SHADOWING = NoShadow; // disable shadow mapping.
- HAZING = NoHaze; // shut off hazing.
-
- HITHER_Z = 10; // default Z clipping at these values.
- YON_Z = 1000;
- }
-
- MESHCLASS::~MESHCLASS(void) // destructor.
- {
- if (Light != NULL)
- delete Light;
- if (Camera != NULL)
- delete Camera;
- if (ObjectHead != NULL)
- delete ObjectHead;
- if (MeshList != NULL)
- delete MeshList;
- }
-
- void MESHCLASS::CreateMeshList(void)
- {
- if (MeshList != NULL)
- delete MeshList;
- MeshList = new POLYGONCLASS *[totalfaces]; // need to allocate for MeshList.
- if (MeshList==NULL)
- Error("Not enough memory\n");
- }
-
- void MESHCLASS::ResetOrigin(void) // put mesh back to 0,0,0 (world coords)
- {
- Camera[_CURRENTCAMERA_].SetViewAngle(0,0,0);
- Camera[_CURRENTCAMERA_].SetViewPoint(0,0,0);
- }
-
- void MESHCLASS::SetMaxTransparency(int Levels)
- {
- MaxTransLevel = Levels;
- }
-
- void MESHCLASS::SetTransparencyLevel(int delta)
- {
- if (HAZING) // can't have both transparency and hazing.
- return;
-
- translevel+=delta;
- TRANSPARENCY=Transparent;
-
- if (translevel<0)
- {
- translevel=-1;
- TRANSPARENCY=Opaque; // fully visible.
- }
- else
- if (translevel>MaxTransLevel)
- {
- translevel=MaxTransLevel;
- }
- }
-
- void MESHCLASS::SetShading(int Shade)
- {
- SHADING = Shade;
- }
-
- void MESHCLASS::SetTextureMapping(int mode)
- {
- TEXTUREMAPPED = mode;
- }
-
- void MESHCLASS::SetHazing(int mode)
- {
- HAZING = mode;
- TRANSPARENCY=Opaque; // shut off.
- }
-
- void MESHCLASS::SetTransparency(int mode)
- {
- TRANSPARENCY=mode;
- HAZING=NoHaze; // shut off.
- }
-
- void MESHCLASS::SetMorph(int mode)
- {
- MORPHING = mode;
- }
-
- void MESHCLASS::SetShadow(int Mode)
- {
- SHADOWING = Mode;
- }
-
- void MESHCLASS::SetTSRVectors(int angle_x, int angle_y, int angle_z,
- int transx, int transy, int transz)
- {
- velangx+=angle_x; // change velocity of rotation angles.
- velangy+=angle_y;
- velangz+=angle_z;
-
- tx=transx;
- ty=transy;
- tz=transz;
- }
-
- void MESHCLASS::ResetTSRVectors(void)
- {
- velangx=0;
- velangy=0;
- velangz=0;
-
- angx=0;
- angy=0;
- angz=0;
-
- tx=ty=tz=0;
- }
-
- void MESHCLASS::MoveCamera(int angle_x, int angle_y, int angle_z,
- float viewx, float viewy, float viewz)
- {
- Camera[_CURRENTCAMERA_].MoveViewAngle(angle_x,angle_y,angle_z);
- Camera[_CURRENTCAMERA_].MoveViewPoint(viewx,viewy,viewz);
- }
-
- void MESHCLASS::_3DPipeLine(void)
- {
- Camera[_CURRENTCAMERA_].CreateCameraMatrix(CameraMatrix);
- CreateTSR_Matrix();
- ObjectCull(CULL_XYZ);
- DepthSort();
- Render();
- }
-
- void MESHCLASS::Push(OBJECTCLASS *ThisObject,int Status)
- {
-
- switch (Status)
- {
- case PARENT:
-
- if (ObjectHead == NULL) // first object.
- {
- ObjectHead = ThisObject;
- ThisObject->morphsteps = 1/(float)100; // morph in 100 steps.
- ThisObject->MorphSource = ThisObject; // reset Starting morph to Parent.
- ThisObject->NextMorphObject = ThisObject; // point back to itself for circular list.
- }
- else
- {
- OBJECTCLASS *temp;
- temp = ObjectHead;
-
- while (temp->NextObject != NULL)
- temp = temp->NextObject;
-
- ThisObject->morphsteps = 1/(float)100; // morph in 100 steps.
- ThisObject->MorphSource = ThisObject; // reset Starting morph to Parent.
- ThisObject->NextMorphObject = ThisObject; // point back to itself for circular list.
- temp->NextObject = ThisObject;
- }
- break;
-
- case CHILD:
- if (ObjectHead == NULL)
- {
- Error("Trying to initialize CHILD without PARENT\n");
- }
- else
- {
- OBJECTCLASS *temp, temp2;
- temp = ObjectHead;
-
- while (temp->NextObject != NULL)
- temp = temp->NextObject;
-
- ThisObject->NextMorphObject = temp->NextMorphObject; // point back to parent. Circular list.
- temp->NextMorphObject = ThisObject;
- }
- break;
- }
- }
-
- int MESHCLASS::SetWorldXYZ(int ObjectID,float wx,float wy,float wz)
- {
- OBJECTCLASS *temp;
-
- temp=ObjectHead;
-
- while ( (temp != NULL) && (temp->ObjectID != ObjectID) )
- {
- OBJECTCLASS *temp2;
-
- temp2=temp->NextMorphObject;
- while ( (temp2 != temp) && (temp2->ObjectID != ObjectID) ) // Search Children.
- temp2=temp2->NextMorphObject;
-
- if (temp2->ObjectID == ObjectID)
- {
- temp2->worldx = wx;
- temp2->worldy = wy;
- temp2->worldz = wz;
- return (SUCCESS);
- }
- temp=temp->NextObject;
- }
-
- if (temp->ObjectID == ObjectID)
- {
- temp->worldx = wx;
- temp->worldy = wy;
- temp->worldz = wz;
- return (SUCCESS);
- }
- else
- return (FAILURE);
- }
-
- void MESHCLASS::SetCurrentCamera(int camera)
- {
- _CURRENTCAMERA_ = camera;
- }
-
- void MESHCLASS::ObjectCull(int Mode)
- {
- OBJECTCLASS *ThisObject;
- float radius;
- float xsphere,ysphere,zsphere,xcompare,ycompare;
-
- ThisObject=ObjectHead; // point to head of list.
- meshindex=0; // reset, for MeshList.
- shadowindex=0; // reset how many shadows.
-
- POINT3D *viewpoint, *lightsource, *infinitelightsource;
- viewpoint=Camera[_CURRENTCAMERA_].GetViewPoint();
- lightsource=Light[0].GetLight();
- infinitelightsource=Light[0].GetInfiniteLight();
-
-
- // if (MORPHING) // These 2 lines are only for the demo purposes because
- // ThisObject=ThisObject->NextObject; // I only want the 2nd Parent object to morph not the first.
- // Take these lines out for your own implementation and remove ( // ) from while statement and continues.
-
- while ( ThisObject != NULL)
- {
-
- ThisObject=ThisObject->GetMorphObject(); // if morph enabled, return object else return root object.
-
- ThisObject->Local2Camera(CameraMatrix, CENTER); // 1 means use world pos to transform.
- ThisObject->GetCenterStats(&radius,&xsphere,&ysphere,&zsphere);
-
- switch (Mode)
- {
- case CULL_Z:
- if ( ((zsphere-radius) > YON_Z) ||
- ((zsphere+radius) < HITHER_Z) )
- {
- ThisObject=ThisObject->NextObject;
- continue; // Not visible!
- }
- else
- {
- ThisObject->TransformObject(TSR_Matrix);
- ThisObject->Local2Camera(CameraMatrix,VERTICES);
- ThisObject->HSR_Shade(viewpoint,lightsource);
- ThisObject->DoShadows(infinitelightsource);
- ThisObject->PolyCull(Mode);
- }
- break;
-
- case CULL_XYZ:
- if ( ((zsphere-radius) > YON_Z) ||
- ((zsphere+radius) < HITHER_Z) )
- {
- ThisObject=ThisObject->NextObject;
- continue;
- }
-
- xcompare = HALF_SCREEN_WIDTH_VD*zsphere;
- if ( ((xsphere-radius) > xcompare) ||
- ((xsphere+radius) < -xcompare) )
- {
- ThisObject=ThisObject->NextObject;
- continue;
- }
-
- ycompare = HALF_SCREEN_HEIGHT_VD*zsphere;
- if ( ((xsphere-radius) > ycompare) ||
- ((xsphere+radius) < -ycompare) )
- {
- ThisObject=ThisObject->NextObject;
- continue;
- } // It passed all tests --> object is visible.
-
- ThisObject->TransformObject(TSR_Matrix);
- ThisObject->Local2Camera(CameraMatrix,VERTICES);
- ThisObject->HSR_Shade(viewpoint,lightsource);
- ThisObject->DoShadows(infinitelightsource);
- ThisObject->PolyCull(Mode);
- break;
- default:
- break;
- } // end switch.
- ThisObject=ThisObject->NextObject;
- } // end while.
- }
-
- void MESHCLASS::CreateTSR_Matrix(void)
- {
- double Xa,Ya,Za;
- float Sx,Cx,Sy,Cy,Sz,Cz;
-
- angx+=velangx;
- angy+=velangy;
- angz+=velangz;
-
- Xa = -angx*DEGREES_TO_RADIANS;
- Ya = -angy*DEGREES_TO_RADIANS;
- Za = -angz*DEGREES_TO_RADIANS;
-
- Sx = (float)sin ( Xa );
- Cx = (float)cos ( Xa );
- Sy = (float)sin ( Ya );
- Cy = (float)cos ( Ya );
- Sz = (float)sin ( Za );
- Cz = (float)cos ( Za );
-
- TSR_Matrix[0][0] = Cy*Cz;
- TSR_Matrix[0][1] = Cy*Sz;
- TSR_Matrix[0][2] = -Sy;
- TSR_Matrix[0][3] = 0;
-
- TSR_Matrix[1][0] = Sx*Sy*Cz-Cx*Sz;
- TSR_Matrix[1][1] = Sx*Sy*Sz+Cx*Cz;
- TSR_Matrix[1][2] = Sx*Cy;
- TSR_Matrix[1][3] = 0;
-
- TSR_Matrix[2][0] = Cx*Sy*Cz+Sx*Sz;
- TSR_Matrix[2][1] = Cx*Sy*Sz-Sx*Cz;
- TSR_Matrix[2][2] = Cx*Cy;
- TSR_Matrix[2][3] = 0;
-
- }
-
- void MESHCLASS::DepthSort(void)
- {
- if (meshindex != 0)
- {
- ComputeAvgZ();
- qsort( &(MeshList[shadowindex]), meshindex-shadowindex,
- sizeof( POLYGONCLASS *), PolyCompare );
- }
- }
-
- void MESHCLASS::Render(void)
- {
- int pindex;
- int SHADOW;
- float x0,y0,z0,x1,y1,z1,x2,y2,z2;
- POLYGONCLASS *ThisPolygon;
-
- for (pindex=0;pindex<meshindex;pindex++)
- {
- ThisPolygon = MeshList[pindex];
- SHADOW = ThisPolygon->shadowvisible;
-
- if (SHADOW)
- {
- x0 = (ThisPolygon->shadow[0]).x;
- y0 = (ThisPolygon->shadow[0]).y;
- z0 = (ThisPolygon->shadow[0]).z;
-
- x1 = (ThisPolygon->shadow[1]).x;
- y1 = (ThisPolygon->shadow[1]).y;
- z1 = (ThisPolygon->shadow[1]).z;
-
- x2 = (ThisPolygon->shadow[2]).x;
- y2 = (ThisPolygon->shadow[2]).y;
- z2 = (ThisPolygon->shadow[2]).z;
-
- ThisPolygon->shadowvisible = NoShadow; // reset.
- }
- else
- {
- x0 = (ThisPolygon->Vertex[0])->x;
- y0 = (ThisPolygon->Vertex[0])->y;
- z0 = (ThisPolygon->Vertex[0])->z;
-
- x1 = (ThisPolygon->Vertex[1])->x;
- y1 = (ThisPolygon->Vertex[1])->y;
- z1 = (ThisPolygon->Vertex[1])->z;
-
- x2 = (ThisPolygon->Vertex[2])->x;
- y2 = (ThisPolygon->Vertex[2])->y;
- z2 = (ThisPolygon->Vertex[2])->z;
- }
-
- long ix1,iy1,ix2,iy2,ix3,iy3;
-
- _X1 = ix1 = (long)(HALF_SCREEN_WIDTH + x0*VIEWDISTANCE/z0);
- _Y1 = iy1 = (long)(HALF_SCREEN_HEIGHT - y0*VD_ASPECTRATIO/z0);
-
- _X2 = ix2 = (long)(HALF_SCREEN_WIDTH + x1*VIEWDISTANCE/z1);
- _Y2 = iy2 = (long)(HALF_SCREEN_HEIGHT - y1*VD_ASPECTRATIO/z1);
-
- _X3 = ix3 = (long)(HALF_SCREEN_WIDTH + x2*VIEWDISTANCE/z2);
- _Y3 = iy3 = (long)(HALF_SCREEN_HEIGHT - y2*VD_ASPECTRATIO/z2);
-
- switch ( TEXTUREMAPPED | SHADING | TRANSPARENCY | SHADOW | HAZING )
- {
- case WireFrame:
- _ColorIndex=ThisPolygon->color+SHADES;
- Scan_Convert_Wire();
- break;
-
- case Constant:
- _ColorIndex = ThisPolygon->color + (ThisPolygon->Vertex[0])->Intensity;
- Scan_Convert_Lambert();
- break;
-
- case Lambert:
- _ColorIndex = ThisPolygon->color + (ThisPolygon->Vertex[0])->Intensity;
- Scan_Convert_Lambert();
- break;
-
- case Gouraud:
- _I1 = (ThisPolygon->Vertex[0])->Intensity;
- _I2 = (ThisPolygon->Vertex[1])->Intensity;
- _I3 = (ThisPolygon->Vertex[2])->Intensity;
- _ColorIndex = ThisPolygon->color;
- Scan_Convert_Gouraud();
- break;
-
- case Phong:
- _A1 = (ThisPolygon->Vertex[0])->Intensity;
- _A2 = (ThisPolygon->Vertex[1])->Intensity;
- _A3 = (ThisPolygon->Vertex[2])->Intensity;
- _ColorIndex = ThisPolygon->color;
- Scan_Convert_Phong();
- break;
-
- case WireFrame_Texture: // just call same function again.
- _ColorIndex=ThisPolygon->color+SHADES;
- Scan_Convert_Wire();
- break;
-
- case Constant_Texture:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _ColorIndex = SHADES;
- Scan_Convert_TextureL();
- break;
-
- case Lambert_Texture:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _ColorIndex = (ThisPolygon->Vertex[0])->Intensity;
- Scan_Convert_TextureL();
- break;
-
- case Gouraud_Texture:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _I1 = (ThisPolygon->Vertex[0])->Intensity;
- _I2 = (ThisPolygon->Vertex[1])->Intensity;
- _I3 = (ThisPolygon->Vertex[2])->Intensity;
- Scan_Convert_TextureG();
- break;
-
- case Phong_Texture:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _A1 = (ThisPolygon->Vertex[0])->Intensity;
- _A2 = (ThisPolygon->Vertex[1])->Intensity;
- _A3 = (ThisPolygon->Vertex[2])->Intensity;
- Scan_Convert_TextureP();
- break;
-
- case WireFrame_Trans:
- _ColorIndex=ThisPolygon->color+SHADES;
- Scan_Convert_Wire();
- break;
-
- case Constant_Trans:
- _ColorIndex = ThisPolygon->color + (ThisPolygon->Vertex[0])->Intensity;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Lambert_Trans:
- _ColorIndex = ThisPolygon->color + (ThisPolygon->Vertex[0])->Intensity;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Gouraud_Trans:
- _I1 = (ThisPolygon->Vertex[0])->Intensity;
- _I2 = (ThisPolygon->Vertex[1])->Intensity;
- _I3 = (ThisPolygon->Vertex[2])->Intensity;
- _ColorIndex = ThisPolygon->color;
- _TransLevel = translevel;
- Scan_Convert_GouraudT();
- break;
-
- case Phong_Trans:
- _A1 = (ThisPolygon->Vertex[0])->Intensity;
- _A2 = (ThisPolygon->Vertex[1])->Intensity;
- _A3 = (ThisPolygon->Vertex[2])->Intensity;
- _ColorIndex = ThisPolygon->color;
- _TransLevel = translevel;
- Scan_Convert_PhongT();
- break;
-
- case WireFrame_Texture_Trans:
- _ColorIndex=ThisPolygon->color+SHADES;
- Scan_Convert_Wire();
- break;
-
- case Constant_Texture_Trans:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _ColorIndex = SHADES;
- _TransLevel = translevel;
- Scan_Convert_TextureLT();
- break;
-
- case Lambert_Texture_Trans:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _ColorIndex = (ThisPolygon->Vertex[0])->Intensity;
- _TransLevel = translevel;
- Scan_Convert_TextureLT();
- break;
-
- case Gouraud_Texture_Trans:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _I1 = (ThisPolygon->Vertex[0])->Intensity;
- _I2 = (ThisPolygon->Vertex[1])->Intensity;
- _I3 = (ThisPolygon->Vertex[2])->Intensity;
- _TransLevel = translevel;
- Scan_Convert_TextureGT();
- break;
-
- case Phong_Texture_Trans:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _A1 = (ThisPolygon->Vertex[0])->Intensity;
- _A2 = (ThisPolygon->Vertex[1])->Intensity;
- _A3 = (ThisPolygon->Vertex[2])->Intensity;
- _TransLevel = translevel;
- Scan_Convert_TexturePT();
- break;
-
- case WireFrame_Shadow:
- _ColorIndex=ThisPolygon->shadowcolor;
- Scan_Convert_Wire();
- break;
-
- case Constant_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case Lambert_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case Gouraud_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case Phong_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case WireFrame_Texture_Shadow: // just call same function again.
- _ColorIndex=ThisPolygon->shadowcolor;
- Scan_Convert_Wire();
- break;
-
- case Constant_Texture_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case Lambert_Texture_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case Gouraud_Texture_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case Phong_Texture_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- Scan_Convert_Lambert();
- break;
-
- case WireFrame_Trans_Shadow:
- _ColorIndex=ThisPolygon->shadowcolor;
- Scan_Convert_Wire();
- break;
-
- case Constant_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Lambert_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Gouraud_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Phong_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case WireFrame_Texture_Trans_Shadow:
- _ColorIndex=ThisPolygon->shadowcolor;
- Scan_Convert_Wire();
- break;
-
- case Constant_Texture_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Lambert_Texture_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Gouraud_Texture_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case Phong_Texture_Trans_Shadow:
- _ColorIndex = ThisPolygon->shadowcolor;
- _TransLevel = translevel;
- Scan_Convert_LambertT();
- break;
-
- case WireFrame_Haze:
- _ColorIndex=ThisPolygon->color+SHADES;
- Scan_Convert_Wire();
- break;
-
- case Constant_Haze:
- _ColorIndex = ThisPolygon->color + (ThisPolygon->Vertex[0])->Intensity;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Lambert_Haze:
- _ColorIndex = ThisPolygon->color + (ThisPolygon->Vertex[0])->Intensity;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Gouraud_Haze:
- _Z1 = (long)z0;
- _Z2 = (long)z1;
- _Z3 = (long)z2;
- _I1 = (ThisPolygon->Vertex[0])->Intensity;
- _I2 = (ThisPolygon->Vertex[1])->Intensity;
- _I3 = (ThisPolygon->Vertex[2])->Intensity;
- _ColorIndex = ThisPolygon->color;
- Scan_Convert_GouraudH();
- break;
-
- case Phong_Haze:
- _Z1 = (long)z0;
- _Z2 = (long)z1;
- _Z3 = (long)z2;
- _A1 = (ThisPolygon->Vertex[0])->Intensity;
- _A2 = (ThisPolygon->Vertex[1])->Intensity;
- _A3 = (ThisPolygon->Vertex[2])->Intensity;
- _ColorIndex = ThisPolygon->color;
- Scan_Convert_PhongH();
- break;
-
- case WireFrame_Texture_Haze:
- _ColorIndex=ThisPolygon->color+SHADES;
- Scan_Convert_Wire();
- break;
-
- case Constant_Texture_Haze:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _ColorIndex = SHADES;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_TextureLH();
- break;
-
- case Lambert_Texture_Haze:
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _ColorIndex = (ThisPolygon->Vertex[0])->Intensity;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_TextureLH();
- break;
-
- case Gouraud_Texture_Haze:
- _Z1 = (long)z0;
- _Z2 = (long)z1;
- _Z3 = (long)z2;
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _I1 = (ThisPolygon->Vertex[0])->Intensity;
- _I2 = (ThisPolygon->Vertex[1])->Intensity;
- _I3 = (ThisPolygon->Vertex[2])->Intensity;
- Scan_Convert_TextureGH();
- break;
-
- case Phong_Texture_Haze:
- _Z1 = (long)z0;
- _Z2 = (long)z1;
- _Z3 = (long)z2;
- _U1 = ThisPolygon->u0;
- _V1 = ThisPolygon->v0;
- _U2 = ThisPolygon->u1;
- _V2 = ThisPolygon->v1;
- _U3 = ThisPolygon->u2;
- _V3 = ThisPolygon->v2;
- _A1 = (ThisPolygon->Vertex[0])->Intensity;
- _A2 = (ThisPolygon->Vertex[1])->Intensity;
- _A3 = (ThisPolygon->Vertex[2])->Intensity;
- Scan_Convert_TexturePH();
- break;
-
- case WireFrame_Shadow_Haze:
- _ColorIndex=ThisPolygon->shadowcolor;
- Scan_Convert_Wire();
- break;
-
- case Constant_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Lambert_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Gouraud_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Phong_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case WireFrame_Texture_Shadow_Haze:
- _ColorIndex=ThisPolygon->shadowcolor;
- Scan_Convert_Wire();
- break;
-
- case Constant_Texture_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Lambert_Texture_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Gouraud_Texture_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
-
- case Phong_Texture_Shadow_Haze:
- _ColorIndex = ThisPolygon->shadowcolor;
- _AvgZ = (long)ThisPolygon->avgz;
- Scan_Convert_LambertH();
- break;
- }
- }
- }
-
- OBJECTCLASS::OBJECTCLASS(void) // Constructor.
- {
- NextObject = NULL;
- }
-
- OBJECTCLASS::~OBJECTCLASS(void) // Destructor.
- {
-
- }
-
- OBJECTCLASS *OBJECTCLASS::CreateMorphData(void)
- {
- POINT3D *LCoordSource,*LCoordDest;
-
- LCoordSource = MorphSource->LocalCoord;
- LCoordDest = (MorphSource->NextMorphObject)->LocalCoord;
-
- int start,end,count;
- switch (SHADING)
- {
- case Gouraud:
- start=0;
- end=numvertices;
- break;
- case Phong:
- start=0;
- end=numvertices;
- break;
- default:
- start=0;
- end=numvertices/2; // don't need to morph avgnormals for these.
- break;
- }
-
- for (count=start;count<end;count++)
- {
- LCoordSource[count].morphx = 0; // reset. how much to add to each vertices when morphing.
- LCoordSource[count].morphy = 0;
- LCoordSource[count].morphz = 0;
-
- LCoordSource[count].morphdx = ( LCoordDest[count].x -
- LCoordSource[count].x )
- * morphsteps;
- LCoordSource[count].morphdy = ( LCoordDest[count].y -
- LCoordSource[count].y )
- * morphsteps;
- LCoordSource[count].morphdz = ( LCoordDest[count].z -
- LCoordSource[count].z )
- * morphsteps;
- }
-
- OBJECTCLASS *temp;
- temp = MorphSource;
- MorphSource = MorphSource->NextMorphObject; // move source to next object.
-
- return (temp); // return present source object.
- }
-
- OBJECTCLASS *OBJECTCLASS::GetMorphObject(void)
- {
- static float morphcount = 1.0; // CreateMorphData first time through.
- static OBJECTCLASS *morphObject = NULL;
-
- if (MORPHING)
- {
- morphcount += morphsteps; // inc count
-
- if (morphcount > 1.0) // reset.
- {
- morphObject=CreateMorphData();
- morphcount = 0.0;
- }
- }
- else
- {
- morphObject=this; // if Morphing not enabled, just return root object.
- MorphSource=this; // reset MorphSource to root (just in case it changed when morphing).
- }
-
- return (morphObject);
- }
-
- void OBJECTCLASS::GetCenterStats(float *radius, float *xsphere, float *ysphere,
- float *zsphere)
- {
- *radius=this->radius;
- *xsphere=this->xsphere; // in camera coords.
- *ysphere=this->ysphere;
- *zsphere=this->zsphere;
- }
-
- void OBJECTCLASS::TransformObject(MATRIX TSR_Matrix)
- {
- float x,y,z;
- int index,start,end;
-
- switch (SHADING)
- {
- case Gouraud:
- start=0;
- end=numvertices;
- break;
- case Phong:
- start=0;
- end=numvertices;
- break;
- default:
- start=0;
- end=numvertices/2;
- break;
- }
-
- POINT3D *LCoord,*CCoord;
- switch (MORPHING)
- {
- case TRUE:
- for (index=start;index<end;index++)
- {
- LCoord = &( LocalCoord[index] );
- CCoord = &( CameraCoord[index] );
-
- LCoord->morphx += LCoord->morphdx; // get closer to destination object.
- LCoord->morphy += LCoord->morphdy;
- LCoord->morphz += LCoord->morphdz;
-
- x = LCoord->x + LCoord->morphx;
- y = LCoord->y + LCoord->morphy;
- z = LCoord->z + LCoord->morphz;
-
- CCoord->x = x*TSR_Matrix[0][0]+
- y*TSR_Matrix[1][0]+
- z*TSR_Matrix[2][0];
-
- CCoord->y = x*TSR_Matrix[0][1]+
- y*TSR_Matrix[1][1]+
- z*TSR_Matrix[2][1];
-
- CCoord->z = x*TSR_Matrix[0][2]+
- y*TSR_Matrix[1][2]+
- z*TSR_Matrix[2][2];
-
- CCoord->valid = FALSE; // this is used for Gouraud and Phong shading when morphing.
- // reset valid flag. Because when morphing the avgnormal
- // goes out of whack and needs to be renormalized.
- }
- break;
-
- case FALSE:
- for (index=start;index<end;index++)
- {
- LCoord = &( LocalCoord[index] );
- CCoord = &( CameraCoord[index] );
-
- x = LCoord->x; // don't mess with local coords.
- y = LCoord->y;
- z = LCoord->z;
-
- CCoord->x = x*TSR_Matrix[0][0]+
- y*TSR_Matrix[1][0]+
- z*TSR_Matrix[2][0];
-
- CCoord->y = x*TSR_Matrix[0][1]+
- y*TSR_Matrix[1][1]+
- z*TSR_Matrix[2][1];
-
- CCoord->z = x*TSR_Matrix[0][2]+
- y*TSR_Matrix[1][2]+
- z*TSR_Matrix[2][2];
-
- CCoord->valid = FALSE; // this is used for Gouraud shading when morphing. And for Phong shading.
- // reset valid flag. Because when morphing the avgnormal
- // goes out of whack and needs to be renormalized.
- }
- break;
- }
- }
-
- void OBJECTCLASS::Local2Camera(MATRIX CameraMatrix, int Mode)
- {
- int index,start,end;
- float x,y,z;
-
- switch (Mode)
- {
- case CENTER: // just transform object center --> camera.
-
- x=worldx;
- y=worldy;
- z=worldz;
-
- xsphere = x*CameraMatrix[0][0]+
- y*CameraMatrix[1][0]+
- z*CameraMatrix[2][0]+
- CameraMatrix[3][0];
-
- ysphere = x*CameraMatrix[0][1]+
- y*CameraMatrix[1][1]+
- z*CameraMatrix[2][1]+
- CameraMatrix[3][1];
-
- zsphere = x*CameraMatrix[0][2]+
- y*CameraMatrix[1][2]+
- z*CameraMatrix[2][2]+
- CameraMatrix[3][2];
- break;
-
- case VERTICES:
-
- switch (SHADING)
- {
- case Gouraud:
- start=0;
- end=numvertices;
- break;
- case Phong:
- start=0;
- end=numvertices;
- break;
- default:
- start=0;
- end=numvertices/2;
- break;
- }
-
- POINT3D *CCoord;
- for (index=start;index<end;index++)
- {
- CCoord = &( CameraCoord[index] );
-
- x = CCoord->x + worldx;
- y = CCoord->y + worldy;
- z = CCoord->z + worldz;
-
- CCoord->x = x*CameraMatrix[0][0]+
- y*CameraMatrix[1][0]+
- z*CameraMatrix[2][0]+
- CameraMatrix[3][0];
-
- CCoord->y = x*CameraMatrix[0][1]+
- y*CameraMatrix[1][1]+
- z*CameraMatrix[2][1]+
- CameraMatrix[3][1];
-
- CCoord->z = x*CameraMatrix[0][2]+
- y*CameraMatrix[1][2]+
- z*CameraMatrix[2][2]+
- CameraMatrix[3][2];
-
- }
- break;
-
- } // end switch.
- }
-
- void OBJECTCLASS::HSR_Shade(POINT3D *viewpoint, POINT3D *lightsource)
- {
-
- POINT3D normal, avgnormal, sightvector, lightvector, u, v;
- POINT3D **VertexId;
- POLYGONCLASS *ThisPolygon;
- int pindex, vindex, intensity;
- float angle, highlight;
-
- for (pindex=0;pindex<numpoly;pindex++)
- {
- ThisPolygon = &(Polygon[pindex]); // alias for ease of access.
- VertexId = ThisPolygon->Vertex;
-
- MakeVector(VertexId[0],viewpoint,&sightvector);
-
- MakeVector(VertexId[0],VertexId[1],&u);
- MakeVector(VertexId[0],VertexId[2],&v);
- CrossProduct(&u,&v,&normal);
-
- if (SHADOWING)
- CopyPoint3D(&normal,&(ThisPolygon->Normal)); // save. Use later on if Shadows are enabled.
-
- angle=DotProduct(&normal,&sightvector);
-
- if (angle>0) // acute, visible!
- {
- ThisPolygon->visible = TRUE;
-
- switch (SHADING)
- {
- case WireFrame: // no shading needed.
- break;
-
- case Constant: // midpoint is the actual color.
-
- (VertexId[0])->Intensity = HALF_SHADES;
-
- break;
-
- case Lambert:
-
- MakeVector(VertexId[0],lightsource,&lightvector);
- Normalize(&lightvector);
-
- angle=DotProduct(&normal,&lightvector);
-
- if (angle>0) // light is hitting the polygon.
- {
- highlight = (SHADES*angle)*ThisPolygon->Normalength;
- if ( (intensity = AMBIENT + highlight) > SHADES)
- intensity = SHADES;
- (VertexId[0])->Intensity = (int)intensity;
- }
- else
- (VertexId[0])->Intensity = AMBIENT;
-
- break;
-
- case Gouraud:
-
- for (vindex=0;vindex<3;vindex++) // cycle through each vertex in poly.
- {
- MakeVector(VertexId[vindex],lightsource,&lightvector);
- Normalize(&lightvector);
-
- MakeVector(VertexId[vindex],ThisPolygon->AvgNormal[vindex],&avgnormal);
-
- if (MORPHING)
- Normalize(&avgnormal); // because when interpolating, avgnormals goes out of whack.
-
- angle=DotProduct(&avgnormal,&lightvector);
- if (angle>0) // light is hitting the polygon.
- {
- if ( (intensity = AMBIENT + SHADES*angle) > SHADES)
- intensity = SHADES;
- (VertexId[vindex])->Intensity = (int)intensity;
- }
- else
- (VertexId[vindex])->Intensity = AMBIENT;
- }
-
- break;
-
- case Phong:
- for (vindex=0;vindex<3;vindex++) // cycle through each vertex in poly.
- {
- MakeVector(VertexId[vindex],lightsource,&lightvector);
- Normalize(&lightvector);
-
- MakeVector(VertexId[vindex],ThisPolygon->AvgNormal[vindex],&avgnormal);
-
- if (MORPHING)
- Normalize(&avgnormal); // because when interpolating, avgnormals goes out of whack.
-
- angle=DotProduct(&avgnormal,&lightvector);
- if (angle>0) // light is hitting the polygon.
- {
- if (!(VertexId[vindex])->valid)
- {
- angle -= 0.00005; // This is a bit of a kludge. Acos only accepts values between -1 and 1.
- // However the value sometime comes to 1.00000011920929. Really 1 but acos doesn't like it.
- // I could fix this by having more percision in my other routines but what the hell?
-
- angle = (float)acos( (double)angle )*RADIANS_TO_DEGREES; // get actual angle between light and normal vector!
- (VertexId[vindex])->Intensity = (int)angle;
- (VertexId[vindex])->valid = TRUE; // we already got angle for this avgnormal.
- }
- }
- else
- (VertexId[vindex])->Intensity = AMBIENTANGLE;
- }
-
- break;
- } // end switch.
- } // end if visible
- else
- ThisPolygon->visible = FALSE;
- } // end for loop
- }
-
- void OBJECTCLASS::DoShadows(POINT3D *lightsource)
- {
- int vindex,pindex;
- float angle,slope;
- POINT3D lightvector, **VertexId;
- POLYGONCLASS *ThisPolygon;
-
- if (SHADOWING) // only do if enabled.
- {
- for(pindex=0;pindex<numpoly;pindex++)
- {
- ThisPolygon = &(Polygon[pindex]);
- angle=DotProduct(&(ThisPolygon->Normal),lightsource);
-
- if (angle>0) // visible! Do Shadows.
- {
- ThisPolygon->shadowvisible = Shadow;
- VertexId = ThisPolygon->Vertex;
- for(vindex=0;vindex<3;vindex++)
- {
- MakeVector( VertexId[vindex], lightsource, &lightvector);
- Normalize(&lightvector);
-
- slope = 600/lightvector.z; // set shadow 600 units away from object. (looks pretty nice that far.)
-
- (ThisPolygon->shadow[vindex]).x = (VertexId[vindex])->x + slope*lightvector.x;
- (ThisPolygon->shadow[vindex]).y = (VertexId[vindex])->y + slope*lightvector.y;
- (ThisPolygon->shadow[vindex]).z = (VertexId[vindex])->z + 200; // to look good when doing perspective correction.
-
- }
- MeshList[meshindex] = ThisPolygon; // add to beginning of rendering list (drawn first).
- meshindex++;
- shadowindex++; // how many shadows in scene.
- }
- else
- ThisPolygon->shadowvisible = NoShadow;
- } // end for.
- } // end if SHADOW.
- }
-
- void OBJECTCLASS::PolyCull(int Mode)
- {
-
- int index;
- float x1,x2,x3,y1,y2,y3,z1,z2,z3;
- float compare1,compare2,compare3;
- POLYGONCLASS *ThisPolygon;
-
- switch (Mode)
- {
- case CULL_Z:
- for (index=0;index<this->numpoly;index++)
- {
- ThisPolygon = &(this->Polygon[index]);
- if (ThisPolygon->visible)
- { // extract z component.
- z1=(ThisPolygon->Vertex[0])->z;
- z2=(ThisPolygon->Vertex[1])->z;
- z3=(ThisPolygon->Vertex[2])->z;
-
- if ( (z1>HITHER_Z || z2>HITHER_Z || z3>HITHER_Z) &&
- (z1<YON_Z || z2<YON_Z || z3<YON_Z) )
- {
- MeshList[meshindex]=ThisPolygon; // it's visible, add
- meshindex++; // to meshlist for rendering.
- }
- }
- }
- break;
- case CULL_XYZ: // do full polygon culling to frustrum.
- for (index=0;index<this->numpoly;index++)
- {
- ThisPolygon = &(this->Polygon[index]);
- if (ThisPolygon->visible) // only do if visible.
- {
-
- x1=(ThisPolygon->Vertex[0])->x; // extract cameracoords for clipping.
- x2=(ThisPolygon->Vertex[1])->x;
- x3=(ThisPolygon->Vertex[2])->x;
-
- y1=(ThisPolygon->Vertex[0])->y;
- y2=(ThisPolygon->Vertex[1])->y;
- y3=(ThisPolygon->Vertex[2])->y;
-
- z1=(ThisPolygon->Vertex[0])->z;
- z2=(ThisPolygon->Vertex[1])->z;
- z3=(ThisPolygon->Vertex[2])->z;
-
- if (!((z1>HITHER_Z || z2>HITHER_Z || z3>HITHER_Z) &&
- (z1<YON_Z || z2<YON_Z || z3<YON_Z)))
- {
- // is clipped --> don't add to MeshList.
- continue;
- }
-
- compare1=HALF_SCREEN_WIDTH_VD*z1;
- compare2=HALF_SCREEN_WIDTH_VD*z2;
- compare3=HALF_SCREEN_WIDTH_VD*z3;
-
- if (!((x1>-compare1 || x2>-compare2 || x3>-compare3) &&
- (x1<compare1 || x2<compare2 || x3<compare3)))
- {
- // is clipped --> don't add to MeshList.
- continue;
- }
-
- compare1=HALF_SCREEN_HEIGHT_VD*z1;
- compare2=HALF_SCREEN_HEIGHT_VD*z2;
- compare3=HALF_SCREEN_HEIGHT_VD*z3;
-
- if (!((y1>-compare1 || y2>-compare2 || y3>-compare3) &&
- (y1<compare1 || y2<compare2 || y3<compare3)))
- {
- // is clipped --> don't add to MeshList.
- continue;
- }
-
- MeshList[meshindex]=ThisPolygon; // visible, so add to List.
- meshindex++;
- } // end if visible.
- } // end for loop.
- break;
- }
- }
-
- void OBJECTCLASS::PreComputeNormal(int vertex0, int vertex1, int vertex2, int index)
- {
- POINT3D u,v,normal;
- POINT3D *Vertex;
-
- Vertex=this->LocalCoord;
-
- MakeVector(&(Vertex[vertex0]),&(Vertex[vertex1]),&u);
- MakeVector(&(Vertex[vertex0]),&(Vertex[vertex2]),&v);
- CrossProduct(&u,&v,&normal);
- Normalize(&normal); // normalize it!
- // get new normal point.
- // and save in vertex list.
- Vertex[index].x = Vertex[vertex0].x + normal.x;
- Vertex[index].y = Vertex[vertex0].y + normal.y;
- Vertex[index].z = Vertex[vertex0].z + normal.z;
- }
-
- void OBJECTCLASS::ComputeNormalength(int vertex0, int vertex1, int vertex2,
- POLYGONCLASS *ThisPolygon)
- {
- POINT3D u,v,normal;
- POINT3D *Vertex;
-
- Vertex=this->LocalCoord;
-
- MakeVector(&(Vertex[vertex0]),&(Vertex[vertex1]),&u);
- MakeVector(&(Vertex[vertex0]),&(Vertex[vertex2]),&v);
- CrossProduct(&u,&v,&normal);
-
- ThisPolygon->Normalength = 1/Magnitude(&normal);
- }
-
- void OBJECTCLASS::PreComputeAvgNormal(struct tempstruct *polystats)
- {
- int vertex0, vertex1, vertex2, commvertex, count, pindex, avgindex;
- int Found=FALSE;
- float sum;
- POINT3D u, v, normal, avgnormal;
-
- avgindex=numvertices; // start of avgnormals.
-
- POINT3D *LCoord;
- LCoord = LocalCoord;
-
- for(commvertex=0;commvertex<numvertices;commvertex++)
- {
- avgnormal.x=0; avgnormal.y=0; avgnormal.z=0; // reset.
- count=0;
- // look for polys that have a common vertex.
- for(pindex=0;pindex<numpoly;pindex++)
- {
- vertex0=polystats[pindex].p0;
- vertex1=polystats[pindex].p1;
- vertex2=polystats[pindex].p2;
-
- if (vertex0 == commvertex)
- {
- Found=TRUE;
-
- MakeVector( &(LCoord[vertex0]), &(LCoord[vertex1]), &u );
- MakeVector( &(LCoord[vertex0]), &(LCoord[vertex2]), &v );
- CrossProduct(&u,&v,&normal);
-
- Polygon[pindex].AvgNormal[0] = &(CameraCoord[avgindex]);
- }
- else
- if (vertex1 == commvertex)
- {
- Found=TRUE;
-
- MakeVector( &(LCoord[vertex1]), &(LCoord[vertex2]), &u );
- MakeVector( &(LCoord[vertex1]), &(LCoord[vertex0]), &v );
- CrossProduct(&u,&v,&normal);
-
- Polygon[pindex].AvgNormal[1] = &(CameraCoord[avgindex]);
- }
- else
- if (vertex2 == commvertex)
- {
- Found=TRUE;
-
- MakeVector( &(LCoord[vertex2]), &(LCoord[vertex0]), &u );
- MakeVector( &(LCoord[vertex2]), &(LCoord[vertex1]), &v );
- CrossProduct(&u,&v,&normal);
-
- Polygon[pindex].AvgNormal[2] = &(CameraCoord[avgindex]);
- }
-
- if (Found)
- {
- Found=FALSE;
- count++;
- avgnormal.x+=normal.x;
- avgnormal.y+=normal.y;
- avgnormal.z+=normal.z;
- }
- } // end for (pindex).
-
- if (count > 0) // Weired. Some objects don't have all vertices used.
- {
- sum=1/(float)count;
- avgnormal.x = avgnormal.x * sum;
- avgnormal.y = avgnormal.y * sum;
- avgnormal.z = avgnormal.z * sum;
-
- Normalize(&avgnormal);
-
- LCoord[avgindex].x = LCoord[commvertex].x + avgnormal.x;
- LCoord[avgindex].y = LCoord[commvertex].y + avgnormal.y;
- LCoord[avgindex].z = LCoord[commvertex].z + avgnormal.z;
- }
- avgindex++;
- }
- }
-
- void OBJECTCLASS::ComputeRadius(void)
- {
- int index;
- double x,y,z,radius, new_radius,scale;
-
- radius = 0;
-
- for (index=0;index<this->numvertices;index++)
- {
- x=(double)this->LocalCoord[index].x;
- y=(double)this->LocalCoord[index].y;
- z=(double)this->LocalCoord[index].z;
-
- new_radius=(float)sqrt( x*x + y*y + z*z );
- if (new_radius>radius)
- {
- radius=new_radius;
- }
- }
-
- scale=100/radius; // scale it to a good amount.
-
- for (index=0;index<this->numvertices;index++)
- {
- this->LocalCoord[index].x=this->LocalCoord[index].x*scale;
- this->LocalCoord[index].y=this->LocalCoord[index].y*scale;
- this->LocalCoord[index].z=this->LocalCoord[index].z*scale;
- }
-
- this->radius=radius*scale;
- this->maxz=this->maxz*scale;
- }
-
- void OBJECTCLASS::FindCenter(void)
- {
- POINT3D *Vertex;
- int count;
-
- Vertex = this->LocalCoord;
-
- float minx,miny,minz;
- minx=Vertex[0].x;
- miny=Vertex[0].y;
- minz=Vertex[0].z;
-
- for (count=1;count<this->numvertices;count++) // find min x,y,z;
- {
- if ( Vertex[count].x < minx )
- minx=Vertex[count].x;
- if ( Vertex[count].y < miny )
- miny=Vertex[count].y;
- if ( Vertex[count].z < minz )
- minz=Vertex[count].z;
- }
-
- float maxx,maxy,maxz;
- maxx=Vertex[0].x;
- maxy=Vertex[0].y;
- maxz=Vertex[0].z;
-
- for (count=1;count<this->numvertices;count++) // find max x,y,z;
- {
- if ( Vertex[count].x > maxx )
- maxx=Vertex[count].x;
- if ( Vertex[count].y > maxy )
- maxy=Vertex[count].y;
- if ( Vertex[count].z > maxz)
- maxz=Vertex[count].z;
- }
-
- float worldx,worldy,worldz;
- worldx=(minx+maxx)/(float)2;
- worldy=(miny+maxy)/(float)2;
- worldz=(minz+maxz)/(float)2;
-
- for (count=0;count<this->numvertices;count++) // adjust local so it
- { // will be centered around 0,0,0
- Vertex[count].x-=worldx;
- Vertex[count].y-=worldy;
- Vertex[count].z-=worldz;
- }
-
- this->worldx=0;
- this->worldy=0;
- this->worldz=250;
- this->maxz=maxz;
- }
-
- POLYGONCLASS::POLYGONCLASS(void) // Constructor.
- {
-
- }
-
- POLYGONCLASS::~POLYGONCLASS(void) // Destructor.
- {
-
- }
-
- void MakeVector(POINT3D *init, POINT3D *term, POINT3D *vector)
- {
- vector->x = term->x - init->x;
- vector->y = term->y - init->y;
- vector->z = term->z - init->z;
- }
-
- void CrossProduct(POINT3D *u, POINT3D *v, POINT3D *normal)
- {
- normal->x = u->y*v->z - u->z*v->y;
- normal->y = -(u->x*v->z - u->z*v->x);
- normal->z = u->x*v->y - u->y*v->x;
- }
-
- float Magnitude(POINT3D *vector)
- {
- double x,y,z;
-
- x=(double)vector->x; y=(double)vector->y; z=(double)vector->z;
- return( (float)sqrt( x*x+y*y+z*z) );
- }
-
- void Normalize(POINT3D *vector)
- {
- double x,y,z,length;
-
- x=(double)vector->x; y=(double)vector->y; z=(double)vector->z;
-
- length=(float)sqrt( x*x+y*y+z*z );
- if (length == 0)
- length = 1;
-
- vector->x/=length; vector->y/=length; vector->z/=length;
- }
-
- float DotProduct(POINT3D *u, POINT3D *v)
- {
- return( u->x*v->x + u->y*v->y + u->z*v->z );
- }
-
- void CopyPoint3D(POINT3D *source, POINT3D *dest)
- {
- dest->x = source->x;
- dest->y = source->y;
- dest->z = source->z;
- }
-
- void BenchMark(int type)
- {
- _X1=100; // 25 pixels per polygon.
- _Y1=100;
- _X2=107;
- _Y2=100;
- _X3=100;
- _Y3=105;
-
- switch (type)
- {
-
- case Lambert:
- _ColorIndex = 370;
- Scan_Convert_Lambert();
- break;
-
- case Gouraud:
- _ColorIndex=16128;
- _I1=10;
- _I2=50;
- _I3=35;
- Scan_Convert_Gouraud();
- break;
-
- case Phong:
- Scan_Convert_Phong();
- break;
-
- case Lambert_Texture:
- break;
-
- case Gouraud_Texture:
- break;
-
- case Phong_Texture:
- break;
-
- default:
- break;
- }
- }
-